package com.hb.config.shiro;

import com.hb.config.shiro.filter.HbAuthenticationFilter;
import com.hb.config.shiro.realm.AdminRealm;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;

@Log4j2
@Configuration
public class ShiroConfig {

	/**
	 * security management
	 *
	 */
	@Bean
	public DefaultWebSecurityManager securityManager() {
		final DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
		//配置Realm
		defaultSecurityManager.setRealm(shiroRealm());
		return defaultSecurityManager;
	}

	/**
	 * authentication realm;
	 */
	@Bean
	public AdminRealm shiroRealm() {
		AdminRealm shiroRealm = new AdminRealm();
		shiroRealm.setCachingEnabled(true);
		shiroRealm.setAuthenticationCachingEnabled(true);
		shiroRealm.setAuthenticationCacheName("authenticationCache");
		shiroRealm.setAuthorizationCachingEnabled(true);
		shiroRealm.setAuthorizationCacheName("authorizationCache");
		return shiroRealm;
	}


	/**
	 * Shiro life cycle
	 */
	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}

	/**
	 * shiro filter
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean() {
		final ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager());
		LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();
		filtersMap.put("auth", new HbAuthenticationFilter());
		shiroFilterFactoryBean.setFilters(filtersMap);
		LinkedHashMap<String, String> fileters = new LinkedHashMap<>();
		// swagger3
		fileters.put("/v3**/**", "anon");
		fileters.put("/swagger**/**", "anon");
        // login
        fileters.put("/sys/login", "anon");

//        fileters.put("/**", "auth");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(fileters);
		return shiroFilterFactoryBean;
	}


	/**
	 * SessionID Generator
	 */
	@Bean
	public SessionIdGenerator sessionIdGenerator() {
		return new JavaUuidSessionIdGenerator();
	}

	/**
	 * Enable annotation permission verification
	 *
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
		final AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
		return authorizationAttributeSourceAdvisor;
	}

	/**
	 * Configure annotation proxy processing
	 */
	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		final DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return advisorAutoProxyCreator;
	}

	/**
	 * Set default session manager
	 */
	@Bean("sessionManager")
	public DefaultWebSessionManager sessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		Collection<SessionListener> listeners = new ArrayList<>();
		// 配置监听
		sessionManager.setSessionListeners(listeners);
		sessionManager.setGlobalSessionTimeout(2 * 24 * 60 * 60 * 1000);
		sessionManager.setDeleteInvalidSessions(true);
		sessionManager.setSessionIdUrlRewritingEnabled(false);
		sessionManager.setSessionIdCookieEnabled(true);
		return sessionManager;
	}

}
